package com.nokia.example3dgame;

import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.GameCanvas;

public class GameCanvasView extends GameCanvas implements GameStatusListener {

private GameMIDlet midlet;
private GameThread gameThread;
private Game3DManager game3DManager;
private GameSoundManager soundManager;
private Image instructionsImage;
private Image pausedImage;
private Image wellDoneImage;
private Image badLuckImage;
private Image weaponImage;
private Image firedImage;
private boolean firstLoad;
private boolean paused;
private boolean gameOverWellDone;
private boolean gameOverBadLuck;
private boolean weaponFired;
private int score;

public GameCanvasView(GameMIDlet midlet, GameSoundManager soundManager, Image frameworkInstructions,
        Image frameworkPaused, Image frameworkWellDone,
        Image frameworkBadLuck, Image gameWeapon, Image firedImage) {
    super(false);
    this.soundManager = soundManager;
    this.createCanvas(midlet, frameworkInstructions, frameworkPaused,
            frameworkWellDone, frameworkBadLuck, gameWeapon, firedImage);
    this.setFullScreenMode(true);
}

private void createCanvas(GameMIDlet midlet, Image frameworkInstructions,
        Image frameworkPaused, Image frameworkWellDone,
        Image frameworkBadLuck, Image gameWeapon, Image firedImage) {
    this.paused = true;
    this.firstLoad = true;
    this.weaponFired = false;
    this.gameOverBadLuck = false;
    this.gameOverWellDone = false;
    this.instructionsImage = frameworkInstructions;
    this.pausedImage = frameworkPaused;
    this.wellDoneImage = frameworkWellDone;
    this.badLuckImage = frameworkBadLuck;
    this.weaponImage = gameWeapon;
    this.firedImage = firedImage;
    this.midlet = midlet;
    this.gameThread = new GameThread();
    this.game3DManager = new Game3DManager(getWidth(), getHeight());
    this.game3DManager.setGameStatusListener(this);

}

public void paint(Graphics g) {
    this.game3DManager.paint(g);
    drawScore(g);
    drawWeapon(g);
    if (firstLoad) {
        //play the midi file here
        soundManager.playMIDISound(0);
        firstLoad = false;
        drawGreyOut(g);
        g.drawImage(instructionsImage, getWidth() / 2, getHeight() / 2,
                Graphics.HCENTER | Graphics.VCENTER);
    } else if (paused) {
        drawGreyOut(g);
        g.drawImage(pausedImage, getWidth() / 2, getHeight() / 2,
                Graphics.HCENTER | Graphics.VCENTER);
    } else if (gameOverWellDone) {
        drawGreyOut(g);
        g.drawImage(wellDoneImage, getWidth() / 2, getHeight() / 2,
                Graphics.HCENTER | Graphics.VCENTER);
    } else if (gameOverBadLuck) {
        drawGreyOut(g);
        g.drawImage(badLuckImage, getWidth() / 2, getHeight() / 2,
                Graphics.HCENTER | Graphics.VCENTER);
    }
}

private void drawWeapon(Graphics g) {
    if (weaponFired) {
        g.drawImage(firedImage, getWidth() / 2, getHeight() - weaponImage.getHeight() / 2, Graphics.BOTTOM | Graphics.HCENTER);
    }
    g.drawImage(weaponImage, getWidth() / 2, getHeight(), Graphics.BOTTOM | Graphics.HCENTER);
}

private void drawGreyOut(Graphics g) {
    int[] buf = new int[getWidth()];
    for (int i = 0; i < getWidth(); i++) {
        buf[i] = 0x88ffffff;
    }
    g.drawRGB(buf, 0, 0, 0, 0, getWidth(), getHeight(), true);
}

private void drawScore(Graphics g) {
    Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD,
            Font.SIZE_SMALL);
    g.setFont(font);
    int width = font.stringWidth("Score: ");
    g.setColor(27, 179, 23);
    g.drawRect(5, 5, width + 30, 20);
    g.setColor(101, 101, 101);
    g.fillRect(6, 6, width + 29, 19);
    g.setColor(27, 179, 23);
    g.drawString("Score: " + score, 7, 7, Graphics.TOP | Graphics.LEFT);
}

private void checkKeys() {
    if ((!gameOverWellDone) || (!gameOverBadLuck)) {
        boolean leftPressed = false;
        boolean rightPressed = false;
        boolean upPressed = false;
        boolean downPressed = false;
        int keyState = getKeyStates();
        if ((keyState & FIRE_PRESSED) != 0) {
            weaponFired = true;
            game3DManager.setFirePressed();
            //play the first game sound here
            soundManager.playGameSound(0);
        } else {
            weaponFired = false;
        }
        if ((keyState & GameCanvas.LEFT_PRESSED) != 0) {
            leftPressed = true;
        }
        if ((keyState & GameCanvas.RIGHT_PRESSED) != 0) {
            rightPressed = true;
        }
        if ((keyState & GameCanvas.UP_PRESSED) != 0) {
            upPressed = true;
        }
        if ((keyState & GameCanvas.DOWN_PRESSED) != 0) {
            downPressed = true;
        }
        game3DManager.setKeysPressed(leftPressed, rightPressed, upPressed,
                downPressed);
    }
}

protected void updateGame() {
    score = this.game3DManager.updateGame();
    Graphics g = getGraphics();
    paint(g);
    flushGraphics();
}

public void stopGame() {
    this.gameThread.requestStop();
    this.gameThread = null;
}

public void playGame() {
    soundManager.stopMIDISound(0);
    this.paused = false;
    this.gameThread.requestPlay();
}

public void pauseGame() {
    this.paused = true;
    updateGame();
    this.gameThread.requestPause();
}

class GameThread extends Thread {

private boolean pause = true;
private boolean stop = false;
private boolean started = false;

public void requestPlay() {
    this.pause = false;
    if (!started) {
        this.start();
        this.started = true;
    }
}

public void requestPause() {
    this.pause = true;
}

public void requestStop() {
    this.stop = true;
}

public void run() {
    long time = 0;
    long delay = 10;

    while (!stop) {
        time = System.currentTimeMillis();
        if (!pause) {
            checkKeys();
            updateGame();

        }
        time = delay - (System.currentTimeMillis() - time);
        try {
            Thread.sleep((time < 0 ? 0 : time));
        } catch (InterruptedException e) {
        }
    }
}
}

public void gameOver(int reason) {
    if (reason == GameStatusListener.GAME_COMPLETED) {
        gameOverWellDone = true;
        gameThread.requestStop();
        midlet.gameOver();
    } else if (reason == GameStatusListener.PLAYER_DIED) {
        gameOverBadLuck = true;
        gameThread.requestStop();
        midlet.gameOver();
    }

}

public void reset() {
    this.gameThread = null;
    this.game3DManager = null;
    System.gc();
    this.createCanvas(midlet, instructionsImage, pausedImage,
            wellDoneImage, badLuckImage, weaponImage, firedImage);
    this.paused = false;
    //updateGame();
}
}
